<template>
  <q-page class="bg-[#FAFCFF] ud-home-page flex flex-col">
    <div class="ud-card-box flex px-[1%] justify-between align-center h-[160px]">
      <q-card flat class="w-[30%] rounded-lg">
        <q-card-section>待办事项</q-card-section>
        <q-separator inset />
        <q-card-section class="flex justify-around">
          <div class="text-center">
            <p class="text-[32px]">{{ pTodo.maintenanceCount }}</p>
            <p class="text-sm text-[#A2AEC3] font-normal">维修单</p>
          </div>
          <div class="text-center">
            <p class="text-[32px]">{{ pTodo.complaintCount }}</p>
            <p class="text-sm text-[#A2AEC3] font-normal">投诉建议</p>
          </div>
          <div class="text-center">
            <p class="text-[32px]">{{ pTodo.overdueRentCount }}</p>
            <p class="text-sm text-[#A2AEC3] font-normal">房租逾期</p>
          </div>
        </q-card-section>
      </q-card>
      <q-card flat class="w-[42%] rounded-lg">
        <q-card-section class="flex justify-between">
          近一年租金总览
          <q-select
            class="w-50"
            outlined
            v-model="curYearMonth"
            :options="curYearYearOptions"
            dense
            options-dense></q-select>
        </q-card-section>
        <q-separator inset />
        <q-card-section class="flex gap-2">
          <div class="flex-1 flex gap-2 flex-nowrap flex-center">
            <img src="@/assets/images/payment.png" />
            <div>
              <p class="text-[20px] text-[#666] font-semibold">
                {{ rTotalIncome }}
              </p>
              <p class="text-sm text-[#A2AEC3] font-normal">总计收款（元）</p>
            </div>
          </div>
          <div class="flex-1 flex gap-2 flex-nowrap flex-center">
            <div class="ud-pend-payment-box flex flex-center">
              <img src="@/assets/images/money.png" />
            </div>
            <div>
              <p class="text-[20px] text-[#666] font-semibold">{{ rPendingIncome }}</p>
              <p class="text-sm text-[#A2AEC3] font-normal">待收款（元）</p>
            </div>
          </div>
          <div class="flex-1 flex gap-2 flex-nowrap flex-center">
            <img src="@/assets/images/receive_payment.png" />
            <div>
              <p class="text-[20px] text-[#666] font-semibold">
                {{ rTenantRate }}
              </p>
              <p class="text-sm text-[#A2AEC3] font-normal">已交租/总数（户）</p>
            </div>
          </div>
        </q-card-section>
      </q-card>
      <q-card flat class="w-[24%] flex flex-center rounded-lg">建设中...</q-card>
    </div>
    <div class="flex-1 flex align-center py-[2%] px-[1%] justify-between">
      <q-card flat class="w-[30%]">
        <q-card-section class="flex justify-between items-center">待办明细</q-card-section>
        <q-separator inset />
        <q-list class="home-detail-box">
          <q-item v-if="hasRepairDetail" class="py-2">
            <q-item-section class="w-[100px] flex-none">
              <q-chip
                class="ud-fix-order"
                color="red-1"
                text-color="red-12"
                icon="bi-wrench-adjustable">
                维修订单
              </q-chip>
              <p class="text-sm text-[#A2AEC3] mt-2 mb-0">{{ rRepairDetail.date }}</p>
              <p class="text-sm text-[#A2AEC3]">{{ rRepairDetail.time }}</p>
            </q-item-section>
            <q-separator inset vertical class="mx-4" />
            <q-item-section>
              <p class="text-lg mb-0">有新的维修单</p>
              <p class="text-sm text-[#A2AEC3] my-2">
                {{ rRepairDetail.houseNumber }}号房 · {{ rRepairDetail.content }}
              </p>
              <div @click="goRepairDetail">
                <p
                  class="text-sm text-[#2265D4] mb-0 cursor-pointer py-1 px-3 border border-[#DEE3ED] border-solid inline-block">
                  支处理
                </p>
              </div>
            </q-item-section>
          </q-item>
          <q-separator inset />
          <q-item class="py-2">
            <q-item-section class="w-[100px] flex-none">
              <q-chip class="ud-fix-order" color="blue-1" text-color="blue-13" icon="bi-bell">
                交租提醒
              </q-chip>
              <p class="text-sm text-[#A2AEC3] mt-2 mb-0">{{ curDate }}</p>
              <p class="text-sm text-[#A2AEC3]">{{ curTime }}</p>
            </q-item-section>
            <q-separator inset vertical class="mx-4" />
            <q-item-section>
              <p class="text-lg mb-5">25日请前往批量发送交租提醒</p>

              <div @click="goRentDetail">
                <p
                  class="text-sm text-[#2265D4] mb-0 cursor-pointer py-1 px-3 border border-[#DEE3ED] border-solid inline-block">
                  支处理
                </p>
              </div>
            </q-item-section>
          </q-item>
          <q-separator inset />
          <q-item v-if="hasComplaintDetail" class="py-2">
            <q-item-section class="w-[100px] flex-none">
              <q-chip class="ud-fix-order" color="red-1" text-color="red-12" icon="bi-clock">
                投诉建议
              </q-chip>
              <p class="text-sm text-[#A2AEC3] mt-2 mb-0">{{ rComplaintDetail.date }}</p>
              <p class="text-sm text-[#A2AEC3]">{{ rComplaintDetail.time }}</p>
            </q-item-section>
            <q-separator inset vertical class="mx-4" />
            <q-item-section>
              <p class="text-lg mb-0">投诉内容投诉内容</p>
              <p class="text-sm text-[#A2AEC3] my-2">
                {{ rComplaintDetail.houseNumber }}号房 · {{ rComplaintDetail.content }}
              </p>
              <div @click="goComplaintDetail">
                <p
                  class="text-sm text-[#2265D4] mb-0 cursor-pointer py-1 px-3 border border-[#DEE3ED] border-solid inline-block">
                  支处理
                </p>
              </div>
            </q-item-section>
          </q-item>
        </q-list>
      </q-card>
      <div class="w-[68%] flex flex-col gap-6">
        <q-card flat class="flex-1 flex flex-col">
          <div>
            <q-card-section class="flex justify-between items-center">月租金趋势</q-card-section>
            <q-separator inset />
          </div>
          <div class="flex-1">
            <div ref="rentChart" class="w-full h-full"></div>
          </div>
        </q-card>
        <div class="flex-1 flex gap-6">
          <q-card flat class="flex-1 rounded-lg flex flex-col">
            <div>
              <q-card-section>月维修统计</q-card-section>
              <q-separator inset />
            </div>
            <div class="flex-1">
              <div ref="repairChart" class="w-full h-full"></div>
            </div>
          </q-card>
          <q-card flat class="flex-1 rounded-lg flex flex-col">
            <div>
              <q-card-section class="flex justify-between">月投诉统计</q-card-section>
              <q-separator inset />
            </div>
            <div class="flex-1">
              <div ref="complaintChart" class="w-full h-full"></div>
            </div>
          </q-card>
          <q-card flat class="flex-1 flex flex-center rounded-lg">建设中...</q-card>
        </div>
      </div>
    </div>
  </q-page>
</template>

<script setup lang="ts">
  import {
    ref,
    reactive,
    watch,
    inject,
    useTemplateRef,
    onMounted,
    onBeforeUnmount,
    type MaybeRef
  } from 'vue'
  import { getHomeDashboard } from '@/api'
  import { isRequestSuccess } from '@/utils'
  import * as echarts from 'echarts'
  import { date } from 'quasar'

  // 待办事项
  interface ITodo {
    maintenanceCount: number
    complaintCount: number
    overdueRentCount: number
  }
  const pTodo = reactive({
    maintenanceCount: 0,
    complaintCount: 0,
    overdueRentCount: 0
  })
  function setTodo(todo: ITodo) {
    const keys: (keyof ITodo)[] = ['maintenanceCount', 'complaintCount', 'overdueRentCount']
    keys.forEach(key => {
      pTodo[key] = todo[key]
    })
  }

  //  近一年租金总览
  interface IRentSummary {
    paidTenants: number
    pendingIncome: number
    totalIncome: number
    totalTenants: number
    yearMonth: string
    showYearMonth?: string
  }
  const rRentSummary = ref<IRentSummary[]>([])
  const curYearMonth = ref<string | undefined>()
  const curYearYearOptions = ref<string[]>([])
  const rTotalIncome = ref(0)
  const rPendingIncome = ref(0)
  const rTenantRate = ref('0/0')
  function setRentSummary(rentSummaries: IRentSummary[] = []) {
    rRentSummary.value = rentSummaries.reverse().map((rs: IRentSummary) => {
      let showYearMonth = rs.yearMonth
      if (rs.yearMonth) {
        const yms = rs.yearMonth.split('-')
        showYearMonth = `${yms[0]}年${yms[1]}月`
      }
      curYearYearOptions.value.push(showYearMonth)
      rs.showYearMonth = showYearMonth
      return rs
    })
    curYearMonth.value = curYearYearOptions.value[0]
  }
  watch(
    () => curYearMonth.value,
    nv => {
      const found = rRentSummary.value.find(item => item.showYearMonth === nv)
      rTotalIncome.value = found ? found.totalIncome : 0
      rPendingIncome.value = found ? found.pendingIncome : 0
      rTenantRate.value = found ? `${found.paidTenants}/${found.totalTenants}` : `0/0`
    }
  )

  //  待办明细
  const timeStamp = Date.now()
  const curDate = date.formatDate(timeStamp, 'YYYY-MM-DD')
  const curTime = date.formatDate(timeStamp, 'HH:mm:ss')
  interface IDetail {
    date: string
    time: string
    houseNumber: string
    content: string
  }
  const hasRepairDetail = ref(false)
  const hasComplaintDetail = ref(false)
  const rRepairDetail = ref<IDetail>({ date: '', time: '', houseNumber: '', content: '' })
  const rComplaintDetail = ref<IDetail>({ date: '', time: '', houseNumber: '', content: '' })
  const setMenu = inject('setMenu')
  function goRepairDetail() {
    if (setMenu && typeof setMenu === 'function') {
      setMenu('repair')
    }
  }
  function goRentDetail() {
    if (setMenu && typeof setMenu === 'function') {
      setMenu('rent')
    }
  }
  function goComplaintDetail() {
    if (setMenu && typeof setMenu === 'function') {
      setMenu('complaint')
    }
  }

  function setDetails(details: any) {
    hasRepairDetail.value = !!details.latestMaintenance
    hasComplaintDetail.value = !!details.latestComplaint
    const regDate = /T|\s+/
    if (hasRepairDetail.value) {
      const { updatedAt, createdAt, maintenanceHouseNumber, maintenanceProject } =
        details.latestMaintenance || {}
      const _dates = updatedAt || createdAt || ''
      const dates = _dates.split(regDate)
      const houseNumber = maintenanceHouseNumber || ''
      const content = maintenanceProject || ''
      rRepairDetail.value = { date: dates[0], time: dates[1], houseNumber, content }
    }
    if (hasComplaintDetail.value) {
      const { updatedAt, createdAt, complaintHouseNumber, complaintContent } =
        details.latestComplaint || {}
      const _dates = updatedAt || createdAt || ''
      const dates = _dates.split(regDate)
      const houseNumber = complaintHouseNumber || ''
      const content = complaintContent || ''
      rComplaintDetail.value = { date: dates[0], time: dates[1], houseNumber, content }
    }
  }
  // trend charts

  interface ITrend {
    month: string
    income: number
    count: number
  }

  const rRentChart = useTemplateRef<HTMLElement>('rentChart')
  const rRepairChart = useTemplateRef<HTMLElement>('repairChart')
  const rComplaintChart = useTemplateRef<HTMLElement>('complaintChart')
  const chartList: any[] = []

  function initResize() {
    chartList.forEach((chart: any) => {
      chart.resize()
    })
  }
  function initChartInstance(rDom: MaybeRef, option: any) {
    if (rDom.value) {
      const chartInstance = echarts.init(rDom.value)
      chartInstance.setOption(option)
      chartList.push(chartInstance)
    }
  }
  function getChartData(res: any, key: string, yKey: 'income' | 'count' = 'count') {
    const xData: string[] = []
    const yData: number[] = []
    const trendList: ITrend[] = res[key]
    if (Array.isArray(trendList)) {
      trendList.forEach((item: ITrend) => {
        xData.push(`${+item.month}月`)
        yData.push(item[yKey])
      })
    }
    return { xData, yData }
  }
  function getCharOption(option: any, xData: string[]) {
    const dGrid = { show: false, left: '12%', right: '10%', top: '40', bottom: '80' }
    const grid = { ...dGrid, ...(option.grid || {}) }

    const oXAxis = {
      type: 'category',
      data: xData,
      splitLine: { show: false },
      axisTick: { show: false },
      axisLine: {
        lineStyle: { color: '#ccc', width: 1 }
      },
      axisLabel: { showMinLabel: true, fontSize: 10, color: '#333' }
    }
    const xAxis = { ...oXAxis, ...(option.xAxis || {}) }

    const oYAxis = {
      name: '单位(个)',
      type: 'value',
      axisLabel: { showMinLabel: true, color: '#333' },
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed',
          color: 'rgba(0,0,0,0.12)'
        }
      },
      axisLine: { show: false },
      nameTextStyle: { align: 'right' }
    }
    const yAxis = { ...oYAxis, ...(option.yAxis || {}) }

    const oLegend = {
      bottom: 20,
      itemWidth: 20,
      icon: 'roundRect',
      textStyle: {
        color: '#999',
        padding: [0, 10]
      }
    }
    const legend = { ...oLegend, ...(option.legend || {}) }

    const series = option.series || []

    const tooltip = { show: true }

    return { grid, xAxis, yAxis, legend, series, tooltip }
  }
  function initRentChart(res: any) {
    const { xData, yData } = getChartData(res, 'rentTrend', 'income')
    const grid = { left: '5%', right: '2%' }
    const xAxis = { boundaryGap: false }
    const yAxis = { name: '单位(元)', splitLine: { show: false } }
    const legend = { data: ['租金收益'] }
    const series = [
      {
        name: '租金收益',
        data: yData,
        type: 'line',
        symbol: 'none',
        smooth: true,
        itemStyle: {
          color: '#21C3BC'
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {
              offset: 0,
              color: 'rgba(33,195,188,0.38)'
            },
            {
              offset: 1,
              color: 'rgba(255,255,255,0)'
            }
          ])
        }
      }
    ]
    const option = getCharOption({ grid, xAxis, yAxis, legend, series }, xData)
    initChartInstance(rRentChart, option)
  }
  function initRepairChart(res: any) {
    const { xData, yData } = getChartData(res, 'maintenanceTrend')
    const legend = { data: ['维修'] }
    const series = [
      {
        name: '维修',
        data: yData,
        type: 'bar',
        barMinHeight: 2,
        barCategoryGap: '2%',
        barWidth: 10,
        itemStyle: {
          color: '#5146A1'
        }
      }
    ]
    const option = getCharOption({ legend, series }, xData)
    initChartInstance(rRepairChart, option)
  }
  function initComplaintChart(res: any) {
    const { xData, yData } = getChartData(res, 'complaintTrend')
    const legend = { data: ['投诉'] }
    const series = [
      {
        name: '投诉',
        data: yData,
        barMinHeight: 2,
        barCategoryGap: '2%',
        type: 'bar',
        barWidth: 10,
        itemStyle: {
          color: '#F7D44C'
        }
      }
    ]
    const option = getCharOption({ legend, series }, xData)
    initChartInstance(rComplaintChart, option)
  }

  function initCharts(res: any) {
    initRentChart(res)
    initRepairChart(res)
    initComplaintChart(res)

    // 窗口自适应
    window.addEventListener('resize', initResize)
  }

  // 初始化图表
  onMounted(() => {
    getHomeDashboard()
      .then(result => {
        if (isRequestSuccess(result)) {
          const res = result.data.data
          const { todo, todoDetails, rentSummary } = res

          setTodo(todo || {})
          setRentSummary(rentSummary || [])

          setDetails(todoDetails || { latestMaintenance: null, latestComplaint: null })
          initCharts(res)
        }
      })
      .catch(error => {
        console.log(error)
      })
  })

  // 销毁实例
  onBeforeUnmount(() => {
    window.removeEventListener('resize', initResize)
    chartList.forEach((chart: any) => {
      chart.dispose()
    })
  })
</script>
<style scoped>
  .ud-home-page {
    font-family:
      PingFangSC,
      PingFang SC,
      Microsoft YaHei,
      Arial;
    font-weight: 500;
    font-size: 16px;
    color: #333;
  }
  .ud-card-box p {
    margin: 0;
    padding: 0;
  }
  .ud-card-box {
    background: url('@/assets/images/head_bg.png') no-repeat;
  }
  .ud-pend-payment-box {
    width: 50px;
    height: 50px;
    background: linear-gradient(317deg, #f44874 0%, #ff4569 100%);
    border-radius: 6px;
  }
  .ud-fix-order :deep(.q-chip__icon) {
    font-size: 1em;
    margin-right: 8px;
  }
  @media screen and (max-width: 1470px) {
    .ud-home-page {
      font-size: 14px;
    }
    .ud-text-segment-box {
      font-size: 12px;
    }
    .ud-text-segment-box :deep(.mx-2\.5) {
      margin-left: 4px;
      margin-right: 4px;
    }
  }
</style>
